package cn.xshi.common.base;

import java.util.*;
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import cn.hutool.core.collection.CollectionUtil;
import cn.xshi.common.entity.*;
import cn.xshi.common.util.ExceptionUtil;
import cn.xshi.common.cache.redis.RedisUtil;
import cn.xshi.common.constant.SessionConstant;
import cn.xshi.common.constant.SysContanst;
import cn.xshi.common.util.JsonUtil;
import cn.xshi.common.util.StringUtil;
import cn.xshi.common.idgeneration.UUID;
import cn.xshi.common.session.HttpSessionUtils;
import cn.xshi.oauth.dao.OauthAccountDao;
import cn.xshi.oauth.model.OauthAccount;
import cn.xshi.sys.dao.SysAreaRegionDao;
import cn.xshi.sys.dao.SysNotifyDao;
import cn.xshi.sys.dao.SysNotifyReceiverDao;
import cn.xshi.sys.dao.SysUserInfoDao;
import cn.xshi.sys.model.SysAreaRegion;
import cn.xshi.sys.model.SysNotify;
import cn.xshi.sys.model.SysNotifyReceiver;
import cn.xshi.sys.model.SysUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
 * @Desc Server父类支持
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Component
@Slf4j
@Primary
public class BaseUtils extends UUID {

	@Resource
	HttpSessionUtils httpSessionUtils;

	@Resource
	RedisUtil redisUtil;

	@Resource
	CommonUtils commonUtils;

	@Resource
	OauthAccountDao oauthAccountDao;

	@Resource
	SysAreaRegionDao sysAreaRegionDao;

	@Resource
	SysUserInfoDao sysUserinfoDao;

	@Resource
	private SysNotifyDao sysNotifyDao;

	@Resource
	private SysNotifyReceiverDao sysNotifyReceiverDao;

	/**
	 * 当前登录者姓名
	 * @return
	 */
	public String getCurrentName() {
		try {
			RequestAttributes ra = RequestContextHolder.getRequestAttributes();
			HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
			return commonUtils.getCurrentName(request);
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 查询当前人所在部门id
	 * @return
	 */
	public String getCurrentDepartId(){
		try {
			RequestAttributes ra = RequestContextHolder.getRequestAttributes();
			HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
			return commonUtils.getBaseHttpSessionEntity().getUserInfoEntity().getDepartInfoId();
		} catch (Exception e) {
			log.error("获取系统用户id出现异常：{0}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 查询当前账号id编号
	 * @return
	 */
	public String getCurrentAccountId() {
		try {
			RequestAttributes ra = RequestContextHolder.getRequestAttributes();
			HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
			return commonUtils.getAccountId(request);
		} catch (Exception e) {
			log.error("获取系统用户id出现异常：{0}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 当前当前账号
	 * @return
	 */
	public String getCurrentAccount() {
		try {
			RequestAttributes ra = RequestContextHolder.getRequestAttributes();
			HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
			return commonUtils.getCurrentAccount(request);
		} catch (Exception e) {
			log.error("获取系统用户id出现异常：{0}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 查询当前用户对象信息
	 *
	 * @return
	 */
	public BaseHttpSessionEntity getBaseHttpSessionEntity() {
		try {
			BaseHttpSessionEntity baseHttpSessionEntity = commonUtils.getBaseHttpSessionEntity();
			return baseHttpSessionEntity;
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 当前登录者信息
	 * @return
	 */
	public OauthAccountEntity getCurrentAccountInfo() {
		try {
			OauthAccountEntity oauthAccountEntity = commonUtils.account();
			return oauthAccountEntity;
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 获取当前用户的数据权限
	 * @return
	 */
	public List<String> systemUandM(){
		try {
			List<String> list = commonUtils.systemUandM();
			return list;
		} catch (Exception e) {
			throw new ExceptionUtil("获取systemUandM出现异常："+e.getMessage());
		}
	}

	/**
	 * 判断当前用户是否为超级管理员
	 * @return
	 */
	public boolean isAdmin() {
		try {
			return commonUtils.isAdmin();
		} catch (Exception e) {
			throw new ExceptionUtil("获取systemUandM出现异常："+e.getMessage());
		}
	}

	/**
	 * 获取缓存值
	 * @return
	 */
	public static Object getCache(String key) {
		RequestAttributes ra = RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
		ServletContext sc = request.getSession(false).getServletContext();
		return (String)sc.getAttribute(key);
	}

	/**
	 * 获取缓存值
	 * @return
	 */
	public static String getCacheStr(String key) {
		RequestAttributes ra = RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
		ServletContext sc = request.getSession().getServletContext();
		return (String)sc.getAttribute(key);
	}

	/**
	 * 根据KEY获取平台路径
	 * @param key
	 * @return
	 */
	public List<PathEntity> getSysPathCache(String key) {
		try {
			List<PathEntity> pathList = commonUtils.getSysPathCache(key);
			return pathList;
		} catch (Exception e) {
			throw new ExceptionUtil("获取PathEntity出现异常："+e.getMessage());
		}
	}

	/**
	 * 统一验证错误 通过注解捕捉字段验证错误信息
	 * @param bindingResult
	 * @return
	 */
	public String backFem(BindingResult bindingResult){
		List<FieldError> fieldErrorList = bindingResult.getFieldErrors();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < fieldErrorList.size(); i++) {
			FieldError fieldError =fieldErrorList.get(i);
			sb.append("错误字段消息："+fieldError.getField() +" : "+fieldError.getDefaultMessage()+"<br>");
		}
		return sb.toString();
	}

	/**
	 * 判断当前请求是否异步
	 * @param request
	 * @return
	 */
	public static boolean isAjaxReq(HttpServletRequest request){
		String head = request.getHeader("x-requested-with");
		//XMLHttpRequest为异步 Ext.basex为同步 则Ajax拦截
		if((null != head && (head.equalsIgnoreCase("XMLHttpRequest")|| "Ext.basex".equalsIgnoreCase(head)))) {
			return true;
		}
		return false;
	}

	/**
	 * 根据KEY获取平台字典
	 * @param key
	 * @return
	 */
	public List<DataDictionaryEntity> getSysDataDictionaryFromCache(String key) {
		try {
			return commonUtils.getSysDataDictionaryCache(key);
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 根据父KEY+子Key获取平台字典
	 * @param parentKey
	 * @param subKey
	 * @return
	 */
	public DataDictionaryEntity getSysDataDictionaryFromCache(String parentKey,String subKey) {
		try {
			return commonUtils.getSysDataDictionaryCache(parentKey,subKey);
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 判断IP是否为黑户
	 * @param ip
	 * @return
	 */
	public boolean getSysIpFrozenFromCache(String ip){
		try {
			return commonUtils.getSysIpFrozenCache(ip);
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	//随机生成唯一client.id方法
	public static String getClientId(){
		String nums = "";
		String[] codeChars = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
				"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
				"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
		for (int i = 0; i < 23; i++)
		{
			int charNum = (int)Math.floor(Math.random() * codeChars.length);
			nums = nums + codeChars[charNum];
		}
		return nums;
	}

	/**
	 * 获取账户更多信息
	 * @param userParamInfo
	 * @return
	 */
	public UserParamInfo infoList(UserParamInfo userParamInfo) {
		try {
			Map<String, Object> condition = new HashMap<>();
			if(!StringUtil.isEmpty(userParamInfo.getAccountId())){
				condition.put("accountId",userParamInfo.getAccountId().split(","));
				List<OauthAccount> oauthAccountList = oauthAccountDao.infoList(condition);
				List<UserInfoEntity> userInfoEntities = new ArrayList<>();
				if(CollectionUtil.isNotEmpty(oauthAccountList)){
					for(OauthAccount oauthAccount:oauthAccountList){
						UserInfoEntity userInfoEntity = new UserInfoEntity();
						userInfoEntity.setAccount(oauthAccount.getAccount());
						userInfoEntity.setName(oauthAccount.getName());
						userInfoEntities.add(userInfoEntity);
					}
				}
				userParamInfo.setUserInfoEntities(userInfoEntities);
			}
			return userParamInfo;
		} catch (Exception e) {
			throw new ExceptionUtil("获取UserParamInfo出现异常："+e.getMessage());
		}
	}

	/**
	 * 根据账号id查找账户信息
	 * @param accountId
	 * @return
	 */
	public OauthAccountEntity getAccount(String accountId) {
		try {
			if(StringUtil.isEmpty(accountId)){
				return null;
			}
			OauthAccount oauthAccount = oauthAccountDao.getOauthAccountById(accountId);
			OauthAccountEntity oauthAccountEntity = JsonUtil.fromFastJson(oauthAccount,OauthAccountEntity.class);
			return oauthAccountEntity;
		} catch (Exception e) {
			log.error("获取账户异常：{0}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 根据账号查找账户信息
	 * @param account
	 * @return
	 */
	public OauthAccountEntity getAccountInfoByAccount(String account) {
		try {
			if(StringUtil.isEmpty(account)){
				return null;
			}
			OauthAccount oauthAccount = oauthAccountDao.getSingleOauthAccount(account);
			OauthAccountEntity oauthAccountEntity = JsonUtil.fromFastJson(oauthAccount,OauthAccountEntity.class);
			return oauthAccountEntity;
		} catch (Exception e) {
			log.error("获取账户异常：{0}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 根据 Token查找在线用户
	 * @param token
	 * @return
	 */
	public OauthAccountEntity getOnlineAccount(String token) {
		try {
			if(StringUtil.isEmpty(token)){
				return null;
			}
			String info = getTokenInfo(token);
			BaseHttpSessionEntity baseHttpSessionEntity = JsonUtil.fromAliFastJson(info, BaseHttpSessionEntity.class);
			if(null == baseHttpSessionEntity){
				return null;
			}
			return baseHttpSessionEntity.getOauthAccountEntity();
		} catch (Exception e) {
			log.error("获取在线账户异常：{0}",e);
			return null;
		}
	}

	/**
	 * 根据 accountId查找在线用户Token
	 * @param accountId
	 * @return
	 */
	public BaseResult getOnlineAccountToken(String accountId,HttpHeaders headers) {
		try {
			if(StringUtil.isEmpty(accountId)){
				return null;
			}
			String info = getTokenByAccountId(accountId);
			return new BaseResult(info);
		} catch (Exception e) {
			log.error("获取在线账户Token异常：{0}",e);
			return null;
		}
	}

	/**
	 * 查询行政区域单条记录
	 * @param id
	 * @return
	 */
	public AreaRegionEntity getAreaRegionEntity(String id){
		try {
			if(StringUtil.isEmpty(id)){
				return null;
			}
			SysAreaRegion sysAreaRegion = sysAreaRegionDao.getSysAreaRegionById(id);
			if(null != sysAreaRegion){
				AreaRegionEntity areaRegionEntity = new AreaRegionEntity();
				areaRegionEntity.setCode(sysAreaRegion.getCode());
				areaRegionEntity.setId(sysAreaRegion.getId());
				areaRegionEntity.setName(sysAreaRegion.getName());
				areaRegionEntity.setLatitude(sysAreaRegion.getLatitude());
				areaRegionEntity.setRegionLevel(sysAreaRegion.getRegionLevel());
				areaRegionEntity.setLongitude(sysAreaRegion.getLongitude());
				areaRegionEntity.setParentId(sysAreaRegion.getParentId());
				return areaRegionEntity;
			}

			return null;
		} catch (Exception e) {
			log.error("查询行政区域单条记录出现异常：{0}",e);
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}

	/**
	 * 获取tokeninfo信息
	 * @param token
	 * @return
	 */
	public String getTokenInfo(String token) {
		return httpSessionUtils.getAttribute(SessionConstant.TOKEN_STORE_PATH+token);
	}

	/**
	 * 根据accountId获取token
	 * @param accountId
	 * @return
	 */
	public String getTokenByAccountId(String accountId){
		if(StringUtils.isEmpty(accountId)){
			return null;
		}
		String token = httpSessionUtils.getAttribute(SessionConstant.ACCOUNT_STORE_PATH+accountId);
		return token;
	}

	/**
	 * 根据条件查找用户集合（包含部门编号逗号分隔，岗位编号逗号分隔，用户编号逗号分隔）
	 * @param condition
	 * @return
	 */
	public List<UserInfoEntity> getUserInfoEntityList(Map<String,Object> condition){
		List<SysUserInfo> userInfoEntities = sysUserinfoDao.getSysUserInfoList(condition);
		return JsonUtil.toFastList(userInfoEntities, UserInfoEntity.class);
	}

	/**
	 * 创建站内通知
	 * @param baseNotifyEntity
	 * @return
	 */
	public int createNotify(BaseNotifyEntity baseNotifyEntity){
		try {
			SysNotify sysNotify = JsonUtil.fromAliFastJson(JsonUtil.toFastJson(baseNotifyEntity), SysNotify.class);
			sysNotify.setId(toUUID());
			sysNotify.setCreateBy(SysContanst.SYS_ADMIN_NAME);
			sysNotify.setCreateTime(getDate());
			sysNotifyDao.addSysNotify(sysNotify);
			List<SysNotifyReceiver> notifyReceiverList = sysNotify.getNotifyReceivers();
			if(CollectionUtil.isNotEmpty(notifyReceiverList)){
				for(SysNotifyReceiver notifyReceiver: notifyReceiverList){
					notifyReceiver.setReceiveId(toUUID());
					notifyReceiver.setReceiveTime(getDate());
					notifyReceiver.setNotifyId(sysNotify.getId());
					sysNotifyReceiverDao.addSysNotifyReceiver(notifyReceiver);
				}
			}
			return 1;
		} catch (Exception e) {
			throw new ExceptionUtil(e.getMessage(),e.getCause());
		}
	}
}
